package com.hjm.common.utils.yh;

import java.util.List;

public class ProChannelMsg {

	private String dats = "";
	private StringBuffer sbff = null;
	private LoFunction loFunction = new LoFunction();


	public byte[] packMessage(List<BitMap> list) throws Exception {
		int bitIndex = 0;
		try {
			int len = 8;
			int bitlen = 8;
			int maxbit = 0;
			for (int i = 0; i < list.size(); i++) {
				BitMap bitMap = (BitMap) list.get(i);
				bitIndex = bitMap.getBit();
				len += (bitMap.getVariable() > 0) ? bitMap.getVariable() - 1
						+ bitMap.getDat().length : bitMap.getVariable()
						+ bitMap.getDat().length;
				maxbit = maxbit < bitMap.getBit() ? bitMap.getBit() : maxbit;
			}
			if (maxbit > 64) {
				len = len + 8;
				bitlen = bitlen + 8;
			}
			byte[] body = new byte[len];
			boolean[] bbitMap = new boolean[bitlen * 8 + 1];
			bbitMap[1] = (maxbit > 64) ? true : false;
			int temp = (bbitMap.length - 1) / 8;
			for (int j = 0; j < list.size(); j++) {
				BitMap bitMap = (BitMap) list.get(j);
				bbitMap[bitMap.getBit()] = true;
				byte[] bitmap = loFunction.getByteFromBinary(bbitMap);
				System.arraycopy(bitmap, 0, body, 0, bitmap.length);
				if (bitMap.getVariable() > 0) {
					byte[] varValue = null;
					String lenlens = String.format(DateUtil.appendField("%0",
							Integer.toString((bitMap.getVariable() - 1)), "d"),
							bitMap.getTruelen());
					varValue = loFunction.strToBCDBytes(lenlens);
					if (varValue.length < bitMap.getVariable() - 1) {
						byte[] addlen = new byte[1];
						System.arraycopy(addlen, 0, body, temp, 1);
						temp += 1;
					}
					System.arraycopy(varValue, 0, body, temp, varValue.length);
					temp += varValue.length;
					System.arraycopy(bitMap.getDat(), 0, body, temp,
							bitMap.getDat().length);
					temp += bitMap.getDat().length;
				} else {
					byte dat[] = new byte[bitMap.getLen()];
					dat = bitMap.getDat();
					System.arraycopy(dat, 0, body, temp, dat.length);
					temp += bitMap.getDat().length;
				}
			}
			return body;
		} catch (Exception e) {
			throw e;
		}
	}

	public PMap<String, String> parseMessage(byte[] body, int[][] config,
											 int start) throws Exception {
		try {
			PMap<String, String> packMap = new PMap<String, String>();
			byte[] map = null;
			byte[] map8 = new byte[8];
			System.arraycopy(body, start, map8, 0, 8);
			boolean[] bmap = null;
			boolean[] bmap8 = loFunction.getBinaryFromByte(map8);

			if (bmap8[1]) {
				map = new byte[16];
				System.arraycopy(body, start, map, 0, 16);
				bmap = loFunction.getBinaryFromByte(map);
			} else {
				map = map8;
				bmap = bmap8;
			}

			StringBuffer bitStr = new StringBuffer();
			for (int j = 0; j < bmap.length; j++) {
				if (bmap[j]) {
					bitStr.append(DateUtil.appendField(Integer.toString(j), ","));
				}
			}
			int tmplen = start + map.length;
			sbff = new StringBuffer();
			for (int i = 2; i < bmap.length; i++) {
				if (!bmap[i]) {
					continue;
				}
				byte[] nextData = null;
				int variable = config[i][3];
				int datTureLen = 0;
				int datLen2 = config[i][2];
				if (variable > 0) {
					int varLen = config[i][3];
					varLen = varLen - 1;



					byte[] varValue = new byte[varLen];
					System.arraycopy(body, tmplen, varValue, 0, varValue.length);
					dats = loFunction.byte2HexStr(varValue);
					int datLen = 0;
					datLen = loFunction.bcdToint(varValue);
					if (config[i][1] == 2 || config[i][1] == 4) {
						datTureLen = datLen;
						datLen = loFunction.convertChar(datLen);
					}
					tmplen += varLen;
					nextData = new byte[datLen];
					System.arraycopy(body, tmplen, nextData, 0, nextData.length);
					tmplen += nextData.length;
				} else {
					int datLen = config[i][2];
					datLen = (config[i][1] == 2 || config[i][1] == 4) ? loFunction
							.convertChar(datLen) : (config[i][1] == 3) ? 8 : datLen;
					nextData = new byte[datLen];
					System.arraycopy(body, tmplen, nextData, 0, nextData.length);
					tmplen += datLen;
				}

				int datatype = config[i][1];
				int subNum = (variable > 0) ? datTureLen : datLen2;
				String datastr = (datatype == 1) ? loFunction
						.asciiToString(nextData) : (datatype == 3) ? loFunction
						.byte2HexStr(nextData) : (datatype == 2) ? loFunction
						.bcdTostr(nextData).substring(nextData.length * 2 - subNum) : loFunction
						.bcdTostr(nextData).substring(
								0,
								nextData.length * 2
										- (nextData.length * 2 - subNum));
				packMap.put(Integer.toString(i), datastr);
				appendLogInfo(variable, i, dats, datastr);
			}
			packMap.put("log", sbff.toString());
			packMap.put("map", loFunction.byte2HexStr(map));
			return packMap;
		} catch (Exception e) {
			throw e;
		}
	}

	private void appendLogInfo(int variable, int i, String datLen,
							   String datastr) throws Exception {
		if (variable == 0) {
			sbff.append("[F").append(i).append("]:[").append(datastr)
					.append("]").append(InitConfig.newLine);
		} else {
			datastr = (InitConfig.hiddenField.contains(i)) ? "Sub domain is hidden"
					: datastr;
			sbff.append("[F").append(i).append("]:[").append(datLen)
					.append("] ").append("[").append(datastr).append("]")
					.append(InitConfig.newLine);
		}
	}

}
